﻿#pragma once

#include <string>

class FileFormat
{
public:
	enum FileType
	{
		NONE = 0,
		/**图片格式**/
		JPEG,
		PNG,
		GIF,
		TGA,
		BMP,
		TIFF,
		DDS,
		PVR,
		PKM,
		/**压缩格式**/
		Zip,
		CCZ,
		GZip,
		BZip2,
		LZMA,
		/**普通格式**/
		FSB, //音频
		JSON,
		XML,
		IBCC,
		LUAQ, //luac脚本
	};

	static FileType CheckFormat(unsigned char *data)
	{
		if (IsJPEG(data))
			return FileFormat::JPEG;
		else if (IsPNG(data))
			return FileFormat::PNG;
		else if (IsGIF(data))
			return FileFormat::GIF;
		else if (IsTGA(data))
			return FileFormat::TGA;
		else if (IsBMP(data))
			return FileFormat::BMP;
		else if (IsTIFF(data))
			return FileFormat::TIFF;
		else if (IsDDS(data))
			return FileFormat::DDS;
		else if (IsPVR(data))
			return FileFormat::PVR;
		else if (IsPKM(data))
			return FileFormat::PKM;
		else if(IsZipBuffer(data))
			return FileFormat::Zip;
		else if (IsCCZBuffer(data))
			return FileFormat::CCZ;
		else if (IsGZipBuffer(data))
			return FileFormat::GZip;
		else if (IsBZip2Buffer(data))
			return FileFormat::BZip2;
		else if (IsLZMABuffer(data))
			return FileFormat::LZMA;
		else if(IsFSB(data))
			return FileFormat::FSB;
		else if (IsJSON(data))
			return FileFormat::JSON;
		else if (IsXML(data))
			return FileFormat::XML;
		else if (IsIBCC(data))
			return FileFormat::IBCC;
		else if (IsLUAQ(data))
			return FileFormat::LUAQ;
		else
			return FileFormat::NONE;
	}

	static std::string GetExtension(unsigned char * bytes)
	{
		FileType format = CheckFormat(bytes);

		return GetExtension(format);
	}

	static std::string GetExtension(FileType format)
	{
		std::string name;
		switch (format)
		{
		case FileFormat::JPEG:
			name = ".jpg";
			break;
		case FileFormat::PNG:
			name = ".png";
			break;
		case FileFormat::GIF:
			name = ".gif";
			break;
		case FileFormat::TGA:
			name = ".tga";
			break;
		case FileFormat::BMP:
			name = ".bmp";
			break;
		case FileFormat::TIFF:
			name = ".tif";
			break;
		case FileFormat::DDS:
			name = ".dds";
			break;
		case FileFormat::PVR:
			name = ".pvr";
			break;
		case FileFormat::PKM:
			name = ".pkm";
			break;
		case FileFormat::Zip:
			name = ".zip";
			break;
		case FileFormat::CCZ:
			name = ".ccz";
			break;
		case FileFormat::GZip:
			name = ".gz";
			break;
		case FileFormat::BZip2:
			name = ".bz";
			break;
		case FileFormat::LZMA:
			name = ".lzma";
			break;
		case FileFormat::FSB:
			name = ".fsb";
			break;
		case FileFormat::JSON:
			name = ".json";
			break;
		case FileFormat::XML:
			name = ".xml";
			break;
		case FileFormat::IBCC:
			name = ".ibcc";
			break;
		case FileFormat::LUAQ:
			name = ".luaq";
			break;
		case FileFormat::NONE:
			name = ".data";
			break;
		}

		return name;
	}

	static bool IsZipBuffer(unsigned char * bytes)
	{
		unsigned char Zip_Head[] = { 0x50, 0x4B, 0x03, 0x04 };

		return ByteCompare(bytes, Zip_Head);
	}

	static bool IsCCZBuffer(unsigned char * bytes)
	{
		unsigned char CCZ_Head[] = { 0x43, 0x43, 0x5A }; //第四位 0x21 未加密 0x70 加密

		return ByteCompare(bytes, CCZ_Head);
	}

	static bool IsGZipBuffer(unsigned char * bytes)
	{
		unsigned char GZip_Head[] = { 0x1F, 0x8B, 0x08 };

		return ByteCompare(bytes, GZip_Head);
	}

	static bool IsBZip2Buffer(unsigned char * bytes)
	{
		unsigned char BZip2_Head[] = { 0x42, 0x5A, 0x68 };

		return ByteCompare(bytes, BZip2_Head);
	}

	static bool IsLZMABuffer(unsigned char * bytes)
	{
		unsigned char LZMA_Head[] = { 0x5D, 0x00, 0x00 };

		return ByteCompare(bytes, LZMA_Head);
	}

	static bool IsJPEG(unsigned char * bytes)
	{
		unsigned char JPEG_Head[] = { 0xFF, 0xD8 };

		return ByteCompare(bytes, JPEG_Head);
	}

	static bool IsPNG(unsigned char * bytes)
	{
		unsigned char PNG_Head[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };

		return ByteCompare(bytes, PNG_Head);
	}

	static bool IsGIF(unsigned char * bytes)
	{
		unsigned char GIF_Head[] = { 0x47, 0x49, 0x46, 0x38 };

		return ByteCompare(bytes, GIF_Head);
	}

	static bool IsTGA(unsigned char * bytes)
	{
		unsigned char TGA_Head_1[] = { 0x00, 0x00, 0x02, 0x00, 0x00 };
		unsigned char TGA_Head_2[] = { 0x00, 0x00, 0x10, 0x00, 0x00 };

		return (ByteCompare(bytes, TGA_Head_1) || ByteCompare(bytes, TGA_Head_2));
	}

	static bool IsBMP(unsigned char * bytes)
	{
		unsigned char BMP_Head[] = { 0x42, 0x4D };

		return ByteCompare(bytes, BMP_Head);
	}

	static bool IsTIFF(unsigned char * bytes)
	{
		unsigned char TIFF_Head_1[] = { 0x49, 0x49, 0x2A, 0x00 };
		unsigned char TIFF_Head_2[] = { 0x4D, 0x4D, 0x00, 0x2A };

		return (ByteCompare(bytes, TIFF_Head_1) || ByteCompare(bytes, TIFF_Head_2));
	}

	static bool IsDDS(unsigned char * bytes)
	{
		unsigned char DDS_Head[] = { 0x44, 0x44, 0x53, 0x20, 0x7C };

		return ByteCompare(bytes, DDS_Head);
	}

	static bool IsPVR(unsigned char * bytes)
	{
		unsigned char PVR_Head_1[] = { 0x50, 0x56, 0x52, 0x03 };
		unsigned char PVR_Head_2[] = { 0x50, 0x56, 0x52, 0x21 };

		return (ByteCompare(bytes, PVR_Head_1) || ByteCompare(bytes+44, PVR_Head_2));
	}

	static bool IsPKM(unsigned char * bytes)
	{
		unsigned char PKM_Head[] = { 0x50, 0x4B, 0x4D, 0x20, 0x31, 0x30 };

		return ByteCompare(bytes, PKM_Head);
	}

	static bool IsFSB(unsigned char * bytes)
	{
		unsigned char FSB_Head[] = { 0x46, 0x53, 0x42, 0x35 };

		return ByteCompare(bytes, FSB_Head);
	}

	static bool IsJSON(unsigned char * bytes)
	{
		unsigned char JSON_Head[] = { 0x7B };

		return ByteCompare(bytes, JSON_Head);
	}

	static bool IsXML(unsigned char * bytes)
	{
		unsigned char XML_Head[] = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C };

		return ByteCompare(bytes, XML_Head);
	}

	static bool IsIBCC(unsigned char * bytes)
	{
		unsigned char IBCC_Head[] = { 0x69, 0x62, 0x63, 0x63 };

		return ByteCompare(bytes, IBCC_Head);
	}

	static bool IsLUAQ(unsigned char * bytes)
	{
		unsigned char LUAQ_Head[] = { 0x1B, 0x4C, 0x75, 0x61, 0x51 };
		return ByteCompare(bytes, LUAQ_Head);
	}

	static bool ByteCompare(unsigned char * source, unsigned char target[])
	{
		return memcmp(source, target, sizeof(target)) == 0;
	}
};
